import React,{useContext} from 'react'
// useContext
// 作用：获取有react.createContext()创建，<XxxContext.Provider>添加设置的共享数据的value值
// useContext 可以替代<XxxContext.Consumer>标签，简化获取共享数据的代码
// 实现方式
// 1 在组件顶层或单独的模块中，由react.createContext()创建一个共享数据对象
// 2 在父组件中添加共享数据对象的引用，通过且只能通过<XxxContext.provider value={{xxx.'xxx'}}/>的形式
// 将数据传递给子组件，请注意传值必须使用value={obj}的形式
// 3 若下一层的子组件用不到共享数据对象中的数据，则可以不做任何属性标签传递
// 4 在某一层的子组件需要用到共享数据对象的数据，则可通过<XxxContext.Customer>获取到数据
// 5 在类组件中除了<XxxContext.Customer>标签，可以通过static xxx = XxxContext;但这种形式在函数组件中无法使用
// 简而言之 useContext 是<XxxContext.Customer>的替代品，可以大量简化获取共享数据值的代码

// 基本用法
// useContext(context)函数可以传入1个参数，该参数为共享数据对象的实例，useContext函数会返回该共享对象实例的value值
// 代码形式
// import GlobalContext from './global-context' // 引入共享数据对象
// function Component () {
//     const global = useContext(GlobalContext) // 在函数组件中声明一个变量代表该共享数据对象的value值
//     // 若想获取共享数据对象中的属性XXX的值，直接使用global.xxx即可
//     return (
//         <div>{global.xxxx}</div>
//     )
// }
// 拆解说明
// 1 子组件（函数组件）需要先引入共享数据对象GlabalContext
// 2 内部定义一个常量global，用来接受useContext函数返回GlobalContext的value值
// 3 函数组件在return 时，可以不使用customer标签，而是直接使用global.xx来获取共享数据
// 4 这里执行的依然是单项数据流，只可以获取，而不可以直接更改

// 同时传递多个共享数据值给1个子组件
// 需求
// 1 有两个共享数据对象UserContext,NewsContext
// 2 父组件为AppComponent.子组件为ChildComponent
// 3 父组件需要同时将UserContext.NewContext的数据同时传递给子组件
const UserContext = React.createContext()
const NewsContext = React.createContext()

function AppComponent () {
    return (
        <div>
            <UserContext.Provider value={{name:'lxy'}}>
                <NewsContext.Provider value={{title: 'maharajah'}}>
                    <ChildComponent/>
                </NewsContext.Provider>
            </UserContext.Provider>
        </div>
    )
}

function ChildComponent () {
    const user = useContext(UserContext)
    const news = useContext(NewsContext)
    return (
        <div>
            {user.name}-{news.title}
        </div>
    )
}

// 代码分析：
// 1、父组件同时要实现传递2个共享数据对象value值，需要使用<XxxContext.Provider value={obj}>标签进行2次嵌套。
// 2、子组件使用了useContext，他可以自由随意使用父组件传递过来的共享数据value，并不需要多次嵌套获取。

// 同时将1个共享数据值传递给多个子组件
// <XxxContext.Provider value={{name:'puxiao'}}>
//     <ComponentA />
//     <ComponentB />
//     <ComponentC />
// </XxxContext.Provider>


export default AppComponent;
